﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Diagnostics;

namespace System.Windows.Media.DirectShow.Filters
{
    internal class AudioRendererPin : BaseInputPin
    {

        // Preferrered type
        private AMMediaType[] _mediaTypes = new AMMediaType[] { new AMMediaType {
            MajorType = MediaMajorTypes.Audio,
            SubType = MediaSubTypes.PCM,
            Format = new WaveFormatExtensible {
                FormatTag = 1, // PCM
                BitsPerSample = 16,
                Channels = 2,
                BlockAlign = 4,
                SamplesPerSec = 44100,
                Size= 0,
                AverageBytesPerSecond = 44100*2*16/8, // sampleSize * channels * bitsPerSample / 8
            }
        }};

        private DirectShowMediaStreamSource mediaStreamSource;

        internal AudioRendererPin(IBaseFilter filter)
            : base(filter)
        {
        }

        internal void SetMediaStreamSource(DirectShowMediaStreamSource mediaStreamSource)
        {
            this.mediaStreamSource = mediaStreamSource;
        }

        public override System.Collections.Generic.IEnumerable<AMMediaType> MediaTypes
        {
            get { return _mediaTypes; }
        }

        public override string Name
        {
            get { return "Audio Input Pin"; }
        }

        public override bool ReceiveCanBlock
        {
            get { return true; }
        }

        protected override AllocatorProperties GetAllocatorRequirements()
        {
            return new AllocatorProperties { 
                BuffersCount = 8,
                BufferSize = (this.ConnectedMediaType.SampleSize >= 1000) ? this.ConnectedMediaType.SampleSize : 1000 };
        }

        protected override bool QueryAccept(AMMediaType mediaType)
        {
            if (mediaType.MajorType.Equals(MediaMajorTypes.Audio))
            {
                WaveFormatExtensible format = mediaType.Format as WaveFormatExtensible;
                if (format == null)
                    return false;

                if (format.FormatTag != 1 && format.FormatTag != 353 && format.FormatTag != 354 && format.FormatTag != 85 && format.FormatTag != 255)
                    return false;
                else
                    return true;
            }
            return false;
        }

        protected override void EndOfStream()
        {
            mediaStreamSource.EndOfStream();
        }

        protected override void Receive(IMediaSample sample)
        {
            //Debug.WriteLine("ar {0} {1}", sample.StartTime, sample.EndTime);
            mediaStreamSource.ReceiveMediaSample(sample);

            // Ask for new samples
            if (this.IsPullMode)
                this.RequestNextSample(sample);
        }

        public override void Inactive()
        {
            base.Inactive();

            mediaStreamSource.Stop();
        }
    }
}
